package cn.tedu.work;

import com.rabbitmq.client.*;

import java.io.IOException;

//模拟工作队列模式的消费者
public class WorkConsumer {
    public static void main(String[] args) throws Exception{
        //1.通过连接工厂配置rabbitmq的连接信息
        ConnectionFactory cf = new ConnectionFactory();
        cf.setHost("127.0.0.1");
        cf.setPort(5672); //客户端端口，5672是默认端口，可以省略
        cf.setUsername("guest");
        cf.setPassword("guest");
        //2.创建tcp和channel
        Connection nc = cf.newConnection();
        Channel cc = nc.createChannel();
        //3.创建队列
        /*
          第一个参数：队列名称
          第二个参数：队列是否持久化
          第三个参数：队列是否单独
          第四个参数：队列是否自动删除
          第五个参数：其他属性的设置
         */
        cc.queueDeclare("helloworld",true,false,false,null);
       //4.从指定的queue中消费数据
        /*
           第一个参数：指定队列名
           第二个参数：autoAck，先设置为true
           第三个参数：处理数据的回调函数
           第四个参数：取消接收的回调函数
         */
        //处理接收数据的回调函数
        DeliverCallback deliverCallback = new DeliverCallback() {
            @Override
            public void handle(String s, Delivery delivery) throws IOException {
                //我们要处理的消息在Delivery对象中封装的
                byte[] body = delivery.getBody();
                //需要转成字符串类型
                String msg = new String(body);
                System.out.println("接收到消息:"+msg);
                //可以对msg进行处理了
                //模拟消息处理缓慢的情况
                //遇到一个'.',线程阻塞一秒
                for (int i = 0; i < msg.length(); i++) {
                    if(msg.charAt(i)=='.'){
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                System.out.println(msg+"处理完毕！");
                //发送消息回执
                /*
                   第一个参数：就是回执消息，是一个标签
                   第二个参数：发送多条消息还是一条消息的回执
                 */
                cc.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
            }
        };
        //取消时调用的回调函数
        CancelCallback cancelCallback = new CancelCallback() {
            @Override
            public void handle(String s) throws IOException {

            }
        };
        //设置qos=1
        cc.basicQos(1);
        //第二参数表示的意思就是autoAck，true就是自动ack，改成false使用手动ack
        cc.basicConsume("helloworld",false,deliverCallback,cancelCallback);
    }
}
